# 获取上下文管理器单例
from django.utils import timezone
from functools import wraps

from weiwenhai_Oj.context.utils.out import get_context_manager, context_get, format_context_data
from weiwenhai_Oj.utils.log_utils import log

context_manager = get_context_manager()


def api_context(service_name):
    """
        初始化上下文的装饰器，在调用视图函数之前设置上下文环境
        service_name : 本次的服务名称，用于区分不同服务
    """

    def decorator(func):

        @wraps(func)
        def wrapper(request, *args, **kwargs):
            _request = request.request
            # 清空旧的上下文数据
            context_manager.clear()

            # 在此初始化新的上下文数据
            context_manager.set_value('request_time', timezone.localtime())
            context_manager.set_value('request_url', _request.path)
            context_manager.set_value('service_name', service_name)

            # 如果有用户登录信息，可以将用户信息加入上下文
            if _request.user.is_authenticated:
                context_manager.set_value('user_id', _request.user.id)
                context_manager.set_value('username', _request.user.username)

            # 调用实际的视图函数
            try:
                response = func(request, *args, **kwargs)
            except Exception as e:
                context_manager.set_value('error_message', str(e))
                raise e
            finally:
                log_context()
                context_manager.clear()
            return response

        return wrapper

    return decorator


def log_context():
    """
    记录上下文数据，在视图函数执行结束后，将上下文数据记录到日志中
    """
    file_name = 'api_context_' + context_get('service_name')
    logger = log(file_name)
    logger.info(format_context_data())